package com.ctg.behavior.calc.impala.calculator;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;
import com.ctg.behavior.api.CtCalcStatus;
import com.ctg.behavior.calc.common.CtSQLParam;
import com.ctg.behavior.calc.impala.CtCalculator;
import com.ctg.behavior.calc.impala.builder.userbehavior.CtUBCalcResultBuilder;
import com.ctg.behavior.calc.impala.builder.userbehavior.CtUBReportBuilder;
import com.ctg.behavior.calc.impala.engine.ImpalaSQLEngine;
import com.ctg.behavior.calc.impala.report.userbehavior.CtUBReport;
import com.ctg.behavior.calc.impala.transfer.userbehavior.CtUBTransfer;
import com.ctg.behavior.calc.impala.utils.CtCalculatorUtils;
import com.ctg.behavior.client.impala.common.CtQueryResult;
import com.ctg.behavior.common.calc.CtCalcBody;
import com.ctg.behavior.common.calc.CtCalcResult;
import com.ctg.behavior.common.userbehavior.CtUBCalcBody;
import com.ctg.behavior.common.userbehavior.CtUBCalcData;
import com.ctg.behavior.common.userbehavior.CtUBCalcResult;
import com.ctg.behavior.utils.CtDateUtils;
import com.ctg.behavior.utils.CtStatusUtils;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class CtUBCalculator implements CtCalculator {

	@Autowired
	private CtUBReportBuilder ubReportBuilder;
	@Autowired
	private CtUBTransfer ubTransfer;
	@Autowired
	private ImpalaSQLEngine sqlEngine;
	@Autowired
	private CtUBCalcResultBuilder resultBuilder;

	/****************************************************************
	 * @apiNote: 1.ReportBuilder依据unit参数，生成有时间顺序的report集合
	 * @apiNote: 2.每个report对应一个执行impalaSQL, sqlEngine执行SQL
	 * @apiNote: 3.resultBuilder合并每一次的计算结果
	 */
	@Override
	public CtCalcResult doCalculator(CtCalcBody calcBody) {
		CtUBCalcResult calcResult = new CtUBCalcResult();
		if (!(calcBody instanceof CtUBCalcBody)) {
			log.error("calcBody={}", calcBody.getClass());
			CtStatusUtils.fillStatus(calcResult, CtCalcStatus.BodyNoMatch);
			return calcResult;
		}
		CtUBCalcBody ubCalcBody = (CtUBCalcBody) calcBody;

		CtUBCalcData calcData = new CtUBCalcData();
		calcResult.setValue(calcData);

		log.info("doBuilder-start: {}", CtDateUtils.getCurrentDateSSS());
		log.info("doBuilder,ubCalcBody={}", JSON.toJSONString(ubCalcBody));
		List<CtUBReport> ubReports = ubReportBuilder.doBuilder(ubCalcBody);
		log.info("doBuilder,ubReports={}", JSON.toJSONString(ubReports));
		log.info("doBuilder-end: {}", CtDateUtils.getCurrentDateSSS());

		log.info("time - start: {}", CtDateUtils.getCurrentDateSSS());

		for (CtUBReport oneReport : ubReports) {
			String transferedSQL = ubTransfer.doTransfer(oneReport, CtSQLParam.createParam());
			log.info("one-reportSql={}", transferedSQL);
			CtQueryResult queryResult = sqlEngine.doQuery("", transferedSQL);
			log.info("one-queryResult={}", JSON.toJSONString(queryResult));

			CtCalculatorUtils.fillCalcResult(calcResult, queryResult);
			if (!calcResult.getSuccess()) {
				log.error(queryResult.getCode());
				break;
			}

			calcData = resultBuilder.doBuilder(calcData, queryResult.getRows(), oneReport);
			log.info("one-calcData={}", JSON.toJSONString(calcData));
		}

		log.info("time - end: {}", CtDateUtils.getCurrentDateSSS());
		return calcResult;
	}

}
